﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Printing;
using System.Drawing;
using TradeForm.Properties;
using System.Configuration;
using TradeForm.config;
using System.Xml.Linq;
using System.Xml;
using System.IO;
using System.Windows.Forms;

namespace TradeForm.Print
{
    public class InvoiceDocument : DocumentBase
    {
        //放置配置的字典
        protected Dictionary<string, Setting> dicPrintSets = new Dictionary<string, Setting>();

        public InvoiceDocument()
        { }
        public InvoiceDocument(string defcode)
        {
            this._defCode = defcode;
            getData(defcode);
            loadPrintSettings();

        }

        public InvoiceDocument(string defcode, bool isPrintBack)
        {
            this.IsPrintBack = isPrintBack;
            this._defCode = defcode;
            getData(defcode);
            loadPrintSettings();
        }

        protected override void OnPrintPage(PrintPageEventArgs e)
        {
            Graphics g = e.Graphics;
            g.PageUnit = GraphicsUnit.Millimeter;
            float fontHeight = g.MeasureString("字体测试高度", base.Font).Height;
            if (this.IsPrintBack)
            {
                if (File.Exists(Application.StartupPath + @"\BackImage\发票.JPG"))
                {
                    g.DrawImage(Image.FromFile(Application.StartupPath + @"\BackImage\发票.JPG"), 0, 0, Convert.ToSingle(e.PageBounds.Width * 25.4 / 100),
                   Convert.ToSingle(e.PageBounds.Height * 25.4 / 100));
                }
            }
            if (this.inv != null && this.goodsDetails != null && this.goodsDetails.Count > 0 && this.goodsSum != null)
            {
                g.DrawString(inv.Consignee, base.Font, Brushes.Black, dicPrintSets["Reciever"].PosX, dicPrintSets["Reciever"].PosY);
                //g.DrawString(inv.DestPort, base.Font, Brushes.Black, dicPrintSets["ToPort"].PosX, dicPrintSets["ToPort"].PosY);
                //g.DrawString(inv.FromPort, base.Font, Brushes.Black, dicPrintSets["FromPort"].PosX, dicPrintSets["FromPort"].PosY);

                g.DrawString(inv.InvoiceNo, base.Font, Brushes.Black, dicPrintSets["InvoiceNo"].PosX, dicPrintSets["InvoiceNo"].PosY);
                g.DrawString(inv.ContractNo, base.Font, Brushes.Black, dicPrintSets["ContractNo"].PosX, dicPrintSets["ContractNo"].PosY);
                g.DrawString(inv.InvoiceDate.Value.ToString("yyyy-MM-dd"), base.Font, Brushes.Black, dicPrintSets["InvoiceDate"].PosX, dicPrintSets["InvoiceDate"].PosY);

                g.DrawString(inv.Mark, base.Font, Brushes.Black, dicPrintSets["Mark"].PosX, dicPrintSets["Mark"].PosY);
                g.DrawString(goodsSum.TotalCount.Value.ToString("###,##0") + "  " + goodsSum.TotalCountUnit, base.Font, Brushes.Black, dicPrintSets["TotalCount"].PosX, dicPrintSets["TotalCount"].PosY);
                float lenTotoalCount = g.MeasureString(goodsSum.TotalCount.Value.ToString("###,##0") + "  " + goodsSum.TotalCountUnit, base.Font).Width;
                g.DrawString("OF " + goodsSum.TotalEName, base.Font, Brushes.Black, dicPrintSets["TotalCount"].PosX + lenTotoalCount + 4.0f,
                    dicPrintSets["GoodsCName"].PosY);

                int i = 0;
                float goodspan = 8.0f;
                decimal iTotalQty = 0;
                decimal dTotalAmount = 0.0m;
                string currency = string.Empty;
                bool showGMSNo = false;
                bool showPONo = false;
                bool showHead = false;
                int colCount = 4;
                float colPad = 0.0f;
                float lineToGood = 4.0f;

                foreach (GoodsDetail item in this.goodsDetails)
                {
                    if (!string.IsNullOrEmpty(item.GMSNo) && showGMSNo == false)
                    {
                        showGMSNo = true;
                        colCount++;
                    }
                    if (!string.IsNullOrEmpty(item.PONo) && showPONo==false )
                    {
                        showPONo = true;
                        colCount++;
                    }
                }
                Pen pen = new Pen(Color.Black, 0.2f);
                colPad = (dicPrintSets["GoodsRightPad"].PosX - dicPrintSets["GoodsDesc"].PosX) / colCount;
                foreach (GoodsDetail item in this.goodsDetails)
                {
                    if (!showHead)
                    {
                        if (showGMSNo)
                        {
                            g.DrawString("GMS NO.", base.Font, Brushes.Black, dicPrintSets["GoodsDesc"].PosX, dicPrintSets["GoodsDesc"].PosY);
                        }
                        g.DrawString("ART NO.", base.Font, Brushes.Black, dicPrintSets["GoodsDesc"].PosX + (1 - (showGMSNo ? 0 : 1)) * colPad,
                            dicPrintSets["GoodsDesc"].PosY);
                        if (showPONo)
                        {
                            g.DrawString("PO NO.", base.Font, Brushes.Black, dicPrintSets["GoodsDesc"].PosX + (2 - (showPONo ? 0 : 1)) * colPad,
                                dicPrintSets["GoodsDesc"].PosY);
                        }
                        g.DrawString("QTY.", base.Font, Brushes.Black, dicPrintSets["GoodsDesc"].PosX + (3 - (showGMSNo ? 0 : 1) - (showPONo ? 0 : 1)) * colPad,
                                        dicPrintSets["GoodsDesc"].PosY);
                        g.DrawString("UNIT PRICE.", base.Font, Brushes.Black,
                            dicPrintSets["GoodsDesc"].PosX + (4 - (showGMSNo ? 0 : 1) - (showPONo ? 0 : 1)) * colPad, dicPrintSets["GoodsDesc"].PosY);
                        g.DrawString("AMOUNT.", base.Font, Brushes.Black,
                            dicPrintSets["GoodsDesc"].PosX + (5 - (showGMSNo ? 0 : 1) - (showPONo ? 0 : 1)) * colPad, dicPrintSets["GoodsDesc"].PosY);
                        
                        pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                        g.DrawLine(pen, dicPrintSets["GoodsDesc"].PosX, dicPrintSets["GoodsDesc"].PosY + lineToGood,
                            dicPrintSets["GoodsRightPad"].PosX, dicPrintSets["GoodsDesc"].PosY + lineToGood);
                        showHead = true;
                    }
                    if (showGMSNo)
                    {
                        g.DrawString(item.GMSNo, base.Font, Brushes.Black, dicPrintSets["GoodsDesc"].PosX,
                           dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan);
                    }
                    g.DrawString(item.ArtNo, base.Font, Brushes.Black, dicPrintSets["GoodsDesc"].PosX + (1 - (showGMSNo ? 0 : 1)) * colPad,
                            dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan);
                    if (showPONo)
                    {
                        g.DrawString(item.PONo, base.Font, Brushes.Black, dicPrintSets["GoodsDesc"].PosX + (2 - (showPONo ? 0 : 1)) * colPad,
                            dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan);
                    }
                    g.DrawString(item.Qty.Value.ToString("###,##0") + item.QtyUnit, base.Font, Brushes.Black,
                        dicPrintSets["GoodsDesc"].PosX + (3 - (showGMSNo ? 0 : 1) - (showPONo ? 0 : 1)) * colPad,
                        dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan);
                    iTotalQty += item.Qty.Value;
                    g.DrawString(item.Currency + " " + item.UnitPrice.Value.ToString("###,##0.00"), base.Font, Brushes.Black,
                        dicPrintSets["GoodsDesc"].PosX + (4 - (showGMSNo ? 0 : 1) - (showPONo ? 0 : 1)) * colPad,
                        dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan);
                    g.DrawString(item.Currency + " " + item.Amount.Value.ToString("###,##0.00"), base.Font, Brushes.Black,
                        dicPrintSets["GoodsDesc"].PosX + (5 - (showGMSNo ? 0 : 1) - (showPONo ? 0 : 1)) * colPad,
                        dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan);
                    dTotalAmount += item.Amount.Value;
                    currency = item.Currency;
                    i++;
                }

                
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                g.DrawLine(pen, dicPrintSets["GoodsDesc"].PosX, dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan,
                    dicPrintSets["GoodsRightPad"].PosX, dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan);

                g.DrawString("Total:", base.Font, Brushes.Black, dicPrintSets["GoodsDesc"].PosX, 
                    dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan + 4);
                g.DrawString(iTotalQty.ToString() + " " + goodsDetails[0].QtyUnit, base.Font, Brushes.Black,
                    dicPrintSets["GoodsDesc"].PosX + (3 - (showGMSNo ? 0 : 1) - (showPONo ? 0 : 1)) * colPad,
                    dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan + 4);
                g.DrawString(currency + " " + dTotalAmount.ToString("###,##0.00"), base.Font, Brushes.Black,
                    dicPrintSets["GoodsDesc"].PosX + (5 - (showGMSNo ? 0 : 1) - (showPONo ? 0 : 1)) * colPad,
                    dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan + 4);

                g.DrawString("=========" + (inv.PriceTerms == "FOB" ? (inv.PriceTerms + " " + inv.FromPort) : (inv.PriceTerms + " " + inv.DestPort)) + "=========",
                    base.Font, Brushes.Black, 
                    dicPrintSets["PriceTerms"].PosX,
                    dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan + 10);
                g.DrawString(inv.Remark, base.Font, Brushes.Black, 
                    dicPrintSets["Remark"].PosX,
                    dicPrintSets["GoodsDesc"].PosY + lineToGood + i * goodspan + 18);
            
            }
            if (this._compny != null)
            {
                float widthCName = g.MeasureString(_compny.CName, base.TitleFont).Width;
                float widthEName = g.MeasureString(_compny.EName, base.TitleFont).Width;
                float widthEAddress = g.MeasureString(_compny.EAddress, base.Font).Width;
                float widthTel = g.MeasureString(_compny.Tel, base.Font).Width;

                g.DrawString(_compny.CName, base.TitleFont, Brushes.Black, Convert.ToSingle((210.0 - widthCName) / 2), dicPrintSets["CompanyCName"].PosY);
                g.DrawString(_compny.EName, base.TitleFont, Brushes.Black, Convert.ToSingle((210.0 - widthEName) / 2), dicPrintSets["CompanyEName"].PosY);
                g.DrawString(_compny.EAddress, base.Font, Brushes.Black, Convert.ToSingle((210.0 - widthEAddress) / 2), dicPrintSets["EAddress"].PosY);
                g.DrawString(_compny.Tel, base.Font, Brushes.Black, Convert.ToSingle((210.0 - widthTel) / 2), dicPrintSets["Tel"].PosY);

            }
        }

        protected void loadPrintSettings()
        {
            XElement printSettings = XElement.Load(AppDomain.CurrentDomain.BaseDirectory + @"\config\InvoiceSettings.xml");
            IEnumerable<XElement> settings = null;
            settings = (from el in printSettings.Elements("setting")
                        select el);
            if (settings != null && settings.Count() > 0)
            {
                foreach (XElement item in settings)
                {
                    if (!dicPrintSets.ContainsKey(item.Attribute("name").Value))
                    {

                        Setting set = new Setting();
                        set.Name = item.Attribute("name").Value;
                        set.CName = item.Attribute("cname").Value;
                        set.PosX = Convert.ToSingle(item.Attribute("PosX").Value);
                        set.PosY = Convert.ToSingle(item.Attribute("PosY").Value);
                        dicPrintSets.Add(set.Name, set);
                    }
                    else
                    {
                        dicPrintSets[item.Attribute("name").Value].CName = item.Attribute("cname").Value;
                        dicPrintSets[item.Attribute("name").Value].PosX = Convert.ToSingle(item.Attribute("PosX").Value);
                        dicPrintSets[item.Attribute("name").Value].PosY = Convert.ToSingle(item.Attribute("PosY").Value);
                    }
                }

            }
            else
            {

            }

        }
    }
}
